/*

Gamebots UT Copyright (c) 2002, Andrew N. Marshal, Gal Kaminka
Gamebots UT 2003/2004 port Copyright (c) 2005
       Joe Manojlovich, Tim Garwood, Jessica Bayliss
Gamebots Pogamut derivation Copyright (c) 2007, Michal Bida
	- derived mainly from 2002 Marshal, Kaminka version

All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

   * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
   * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

This software must also be in compliance with the Epic Games Inc. license for mods which states the following: "Your mods must be distributed solely for free, period. Neither you, nor any other person or party, may sell them to anyone, commercially exploit them in any way, or charge anyone for receiving or using them without prior written consent of Epic Games Inc. You may exchange them at no charge among other end-users and distribute them to others over the Internet, on magazine cover disks, or otherwise for free." Please see http://www.epicgames.com/ut2k4_eula.html for more information.

*/

//This class is used for players, remotebots and epic bots
class GBxPawn extends xPawn;
//	dependsOn(xUtil);

#exec OBJ LOAD FILE=PlayerSkins.utx
#exec OBJ LOAD FILE=HumanMaleA.ukx

var string DesiredSkin;

var string TextBubble;
var float TextBubbleSetTime;
var float TextBubbleFadeOut;

replication
{
	reliable if (Role == ROLE_Authority)
		DesiredSkin, TextBubble, TextBubbleSetTime, TextBubbleFadeOut;
}

//Make bot dodge, used by RemoteBots
function RemoteDoDodge(vector Dir)
{
	if (Physics != PHYS_Falling)
		Velocity = BotDodge(Dir);
	SetPhysics(PHYS_Falling);
}

//jumps by specified force
function RemoteJump(float DesiredJumpZ)
{
    PlayDoubleJump();

    if ( !bIsCrouched && !bWantsToCrouch )
    {
        Velocity.Z += DesiredJumpZ;
        SetPhysics(PHYS_Falling);

    //    if ( !bUpdating )
			PlayOwnedSound(GetSound(EST_DoubleJump), SLOT_Pain, GruntVolume,,80);
    }
}

// called if bScriptPostRender is true, overrides native team beacon drawing code
// used by everyone
simulated event PostRender2D(Canvas C, float ScreenLocX, float ScreenLocY)
{
	local PlayerController PC;

	PC = Level.GetLocalPlayerController();

	if ( (PC != None) && (PC.myHUD != None) && (PC != Controller))
	{
		GBxPlayer(PC).GBHUD.NotifySeePawn(C,self,ScreenLocX, ScreenLocY);
	}
}


//We override this function so we can set bot skins
//Used by RemoteBots
simulated function Setup(xUtil.PlayerRecord rec, optional bool bLoadNow)
{

	local string meshName, temp;

	//used just for RemoteBots
	if (DesiredSkin != "")
	{
		LinkMesh(Mesh(DynamicLoadObject(DesiredSkin, class'Mesh')),false);
		//bScriptPostRender = true;
		if (DesiredSkin == "ThunderCrash.JakobM")
		{
			//To the honour of JakobM skin - it is stored elsewhere then other skins
			//We've been using him for long time, so it would be sad to not support him anymore :-)
			Skins[0]=Texture(DynamicLoadObject("DemoPlayerSkins.Jakob_Body", class'Texture'));
			Skins[1]=Texture(DynamicLoadObject("DemoPlayerSkins.Jakob_NewHead", class'Texture'));
		}
		else
		{
		    Divide(DesiredSkin, ".", temp, meshName);

			// This should make most of default built-in UT2004 player meshes work with
			// good textures.
			// TODO: allow to set also these two variables?
			Skins[0]=Texture(DynamicLoadObject("PlayerSkins."$meshName$"BodyA", class'Texture'));
			Skins[1]=Texture(DynamicLoadObject("PlayerSkins."$meshName$"HeadA", class'Texture'));
		}

		ResetPhysicsBasedAnim();
	}
	else
		super.setup(rec, bLoadNow);

}

//we modify this, so we can limit the ammount of damage our bot takes
//Used by all
function TakeDamage(int Damage, Pawn instigatedBy, Vector hitlocation, Vector momentum, class<DamageType> damageType)
{

	Damage = round ( Damage * BotDeathMatch(Level.Game).DamageModifier );

	super.TakeDamage( Damage,  instigatedBy, hitlocation,  momentum, damageType);
}

//This function assures that our bot dies as he is supposed when we want to kill him "manually"
//otherwise had problems with flag not dropping from the corpse, etc.
//Used by RemoteBots
function RemoteRespawnDied()
{
	local NavigationPoint N;
	local Trigger T;

	// make sure to untrigger any triggers requiring player touch
	if ( Controller != none )
	{
		PhysicsVolume.PlayerPawnDiedInVolume(self);
		foreach TouchingActors(class'Trigger',T)
			T.PlayerToucherDied(self);

		// event for HoldObjectives
		//for ( N=Level.NavigationPointList; N!=None; N=N.NextNavigationPoint )
		//	if ( N.bStatic && N.bReceivePlayerToucherDiedNotify )
		ForEach TouchingActors(class'NavigationPoint', N)
			if ( N.bReceivePlayerToucherDiedNotify )
				N.PlayerToucherDied( Self );
	}

	// remove powerup effects, etc.
	RemovePowerups();

}

//Used by RemoteBots right now, but potentially usefull for others too
simulated function SetTextBubble(string Id, string Msg, bool bGlobal, optional float FadeOut)
{

	TextBubbleFadeOut = FadeOut;

	if (FadeOut == -1)
		return;

	if (FadeOut == 0)
		TextBubbleFadeOut = 5;

	TextBubbleSetTime = Level.TimeSeconds;
	if (Id == "")
		TextBubble = Msg;
	else
		TextBubble = "To "$Id$":"$Msg;

}

simulated function SetSkin(string skin, optional xUtil.PlayerRecord rec)
{
//	log("PawnSkinBeforeChange");
//	log("Pawn Mesh: "$Mesh);

//	log("Used PlayerRecord: ");
	//rec = class'xUtil'.static.FindPlayerRecord("Malcolm");
//	log("Rec.MeshName: "$rec.MeshName);
	DesiredSkin = skin;
//	BotSkin = rec;
//	Setup(rec,true);
		/*
	if (Species.static.Setup(self,rec))
		log("Setup returned true");
	else
		log("Setup returned false");
		  */
//	log("PawnSkinAfterChange");
//	log("Pawn Mesh: "$Mesh);
		/*
		PRClass = class<PlayerRecordClass>(DynamicLoadObject(charname$"mod."$charName,class'Class',true));
		if ( PRClass != None )
		{
			PRE = PRClass.Static.FillPlayerRecord();
			PRE.DefaultName = charname;
		}   */

}

//testing function
function Test()
{
	//local int i;

	//class'BotAPI.PathMarker'.default.DrawScale3D = vect(0.075000,0.075000,0.75000);
	//class'BotAPI.PathMarker'.static.StaticSaveConfig();
	/*
	TestActor = Spawn(class'BotAPI.TestMarker', self, , Location, Rotation); //Spawning actor
	//TestActor.SetDrawScale(2);

	TestActor.SetDrawScale3D(vect(10000,5000,5000) / 10000); //Setting DrawScale3D on server
	TestActor.myDrawScale3D=vect(10000,5000,5000);
	TestActor.SetLocation(Location);    */
	//TestActor.DoIt(); //Setting DrawScale3D on client
	//TestActor.SetDrawScale3D(vect(0.001,0.001,2));

	//AttachToBone(TestActor, 'spine');
	//TestActor.SetBase( self, Location + 100 * vector(Rotation) );
	//TestActor.SetLocation(Location + 100 * vector(Rotation));

	//DrawStayingDebugLine(Location,Location + 500 * vector(Rotation),255,0,0);
    //DrawDebugCircle( Location, vect(100,100,100), vect(100,100,100), 500, 2, 0, 255, 255);
    /*Effect1 = Spawn(class'BotAPI.TraceLine', self,, Location, Rotation); //SpeedTrail is already created :).


    AttachToBone(Effect1, 'spine');
    TraceLine(Effect1).BeamDirection = rot(0,0,0);
    TraceLine(Effect1).BeamLength = 200;
	  */

   /* Effect2 = Spawn(class'BotAPI.TestEmitter', self,, Location, Rotation); //SpeedTrail is already created :).
    AttachToBone(Effect1, 'spine');

    Effect2.Emitters[0].StartSizeRange.X.Min = 0.01;
	Effect2.Emitters[0].StartSizeRange.X.Max = Effect2.Emitters[0].StartSizeRange.X.Min;

	for(i = 0; i < Effect2.Emitters[0].Particles.length; i++)
    	Effect2.Emitters[0].Particles[i].StartSize = vect(1,1,1) * 0.01;    */
	//if (Effect1 != None)
	//	AttachToBone(Effect1, 'spine');
	//else
	//	log("jsme v knedlu");
	//DrawLineEffect(Effect1).LaunchBeam(Location + 500 * vector(Rotation),true);
   // AttachToBone(Effect1, 'spine'); //lfoot = Left Foot

    //Effect1.LaunchBeam(Location + 500 * vector(Rotation),true);
	//DrawTraceLine(1,Location + 500 * vector(Rotation),true);


	//Effect1.Trigger();
	//SpawnBeamEffect(Location,Rotation,Location + 500 * vector(Rotation),vect(0,0,0),1);
	//Spawn(BeamEffectClass,,,Location + CollisionHeight * vect(0,0,0.75));
	//DrawStayingDebugLine(Location,Location + 500 * vector(Rotation),255,0,0);

	log("Weve been in test");
}

//not used
simulated function DrawLine(vector Start,vector End)
{
	DrawStayingDebugLine(Start,End,255,0,0);
}

defaultproperties
{
     TextBubble="Testing bubble"
     bScriptPostRender=True
}
